package sps.admin.module.business.workinghours.service;

import java.sql.*;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;
import sps.admin.module.business.workinghours.dao.WorkingHoursDao;
import sps.admin.module.business.workinghours.domain.entity.WorkingHoursEntity;
import sps.admin.module.business.workinghours.domain.form.WorkingHoursAddForm;
import sps.admin.module.business.workinghours.domain.form.WorkingHoursQueryForm;
import sps.admin.module.business.workinghours.domain.form.WorkingHoursUpdateForm;
import sps.admin.module.business.workinghours.domain.form.WorkingOvertimeAnalysisForm;
import sps.admin.module.business.workinghours.domain.vo.*;
import sps.admin.module.system.department.service.DepartmentService;
import sps.admin.module.system.employee.dao.EmployeeDao;
import sps.admin.module.system.employee.domain.entity.EmployeeEntity;
import sps.admin.module.system.employee.domain.vo.EmployeeVO;
import sps.admin.module.system.position.dao.PositionDao;
import sps.admin.util.DateUtils;
import sps.base.common.code.UserErrorCode;
import sps.base.common.enumeration.BanBieTypeEnum;
import sps.base.common.util.SmartBeanUtil;
import sps.base.common.util.SmartLocalDateUtil;
import sps.base.common.util.SmartPageUtil;
import sps.base.common.domain.ResponseDTO;
import sps.base.common.domain.PageResult;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.collections4.CollectionUtils;
import sps.base.module.support.dict.dao.DictValueDao;

import javax.annotation.Resource;

/**
 * 工时功能 Service
 *
 * @Author yjg
 * @Date 2024-09-09 11:02:13
 * @Copyright v1.0
 */

@Service
@Slf4j
public class WorkingHoursService {

    @Value("${third.jiabao.api.driver}")
    String DBDRIVER;

    @Value("${third.jiabao.api.url}")
    String DBURL;

    @Value("${third.jiabao.api.username}")
    String USER;

    @Value("${third.jiabao.api.password}")
    String PASSWORD;

    @Resource
    private WorkingHoursDao workingHoursDao;

    @Resource
    private EmployeeDao employeeDao;

    @Resource
    private DepartmentService departmentService;

    @Resource
    private PositionDao positionDao;


    /**
     * 分页查询
     *
     * @param queryForm
     * @return
     */
    public PageResult<WorkingHoursVO> queryPage(WorkingHoursQueryForm queryForm) {
        queryForm.setDeletedFlag(false);
        Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
        //查询部门
        List<Long> departmentIds = queryForm.getDepartmentIds();
        //查询人员
        List<String> memerNumbers = queryForm.getCheckedMemberNumbers();
        List<WorkingHoursVO> list = workingHoursDao.queryPage(page, queryForm,departmentIds,memerNumbers);
        for (WorkingHoursVO v : list){
            List<String> memberIdList = new ArrayList<>();
            memberIdList.add(v.getJobNumber()+","+v.getName());
            v.setMemberIdList(memberIdList);
            List<String> memberNameList = new ArrayList<>();
            memberNameList.add(v.getJobNumber()+v.getName());
            v.setMemberNameList(memberNameList);
        }
        list.forEach(e -> {
            e.setDeptName(departmentService.getDepartmentPath(e.getDepartmentId()));
            List<Long> id = new ArrayList<>();
            id.add(e.getDepartmentId());
            e.setDepartmentIds(id);
        });
        PageResult<WorkingHoursVO> pageResult = SmartPageUtil.convert2PageResult(page, list);
        return pageResult;
    }

    /**
     * 分页查询
     *
     * @param queryForm
     * @return
     */
    public PageResult<WorkingHoursVO> queryAllowPage(WorkingHoursQueryForm queryForm) {
        queryForm.setDeletedFlag(false);
        Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
        //部门查询
        List<Long> departmentIds = queryForm.getDepartmentIds();
        //查询人员
        List<String> memerNumbers = queryForm.getCheckedMemberNumbers();
        List<WorkingHoursVO> list = workingHoursDao.queryAllowPage(page, queryForm,departmentIds,memerNumbers);
        PageResult<WorkingHoursVO> pageResult = SmartPageUtil.convert2PageResult(page, list);
        List<WorkingHoursVO> entitys = pageResult.getList();
        for(WorkingHoursVO workingHoursVO : entitys){
            workingHoursVO.setCreateUserName(employeeDao.getEmployeeById(workingHoursVO.getCreateUserId()).getActualName());
        }
        return pageResult;
    }

    /**
     * 添加
     */
    public ResponseDTO<String> add(WorkingHoursAddForm addForm) {
        addForm.setDeletedFlag(false);
        List<String> memberIdList = addForm.getMemberIdList();
        for(String memberId :memberIdList){
            EmployeeVO employee = employeeDao.getEmployeeById(Long.valueOf(memberId));
            QueryWrapper<WorkingHoursEntity> entityQueryWrapper = new QueryWrapper<>();
            entityQueryWrapper.eq("job_number",employee.getLoginName());
            entityQueryWrapper.eq("overtime_data",addForm.getOvertimeData());
            entityQueryWrapper.eq("banbie_type",addForm.getBanbieType());
            entityQueryWrapper.eq("overtime_flag",addForm.getOvertimeFlag());
            entityQueryWrapper.eq("deleted_flag",false);
            WorkingHoursEntity entity = workingHoursDao.selectOne(entityQueryWrapper);
            if(entity == null){
                addForm.setName(employee.getActualName());
                addForm.setJobNumber(employee.getLoginName());
                addForm.setDeptName(employee.getDepartmentName());
                addForm.setDepartmentId(employee.getDepartmentId());
                WorkingHoursEntity workingHoursEntity = SmartBeanUtil.copy(addForm, WorkingHoursEntity.class);
                workingHoursDao.insert(workingHoursEntity);
            }
        }
        return ResponseDTO.ok();
    }

    /**
     * 更新
     *
     * @param updateForm
     * @return
     */
    public ResponseDTO<String> update(WorkingHoursUpdateForm updateForm) {
        WorkingHoursEntity workingHoursEntity = SmartBeanUtil.copy(updateForm, WorkingHoursEntity.class);
        workingHoursDao.updateById(workingHoursEntity);
        return ResponseDTO.ok();
    }

    /**
     * 批量删除
     *
     * @param idList
     * @return
     */
    public ResponseDTO<String> batchDelete(List<Integer> idList) {
        if (CollectionUtils.isEmpty(idList)){
            return ResponseDTO.ok();
        }
        List<WorkingHoursEntity> collect = workingHoursDao.selectBatchIds(idList).stream().filter(item -> (item.getAllowFlag() != 1)).collect(Collectors.toList());
        idList = idList.stream().filter(item -> {
            for (WorkingHoursEntity entity : collect) {
                if (entity.getWorkingHoursId() == (long) item) {
                    return true;
                }
            }
            return false;
        }).collect(Collectors.toList());
        List<WorkingHoursEntity> entities = workingHoursDao.selectBatchIds(idList);
        for(WorkingHoursEntity entity : entities){
            entity.setDeletedFlag(true);
            workingHoursDao.updateById(entity);
        }
        return ResponseDTO.ok();
    }

    /**
     * 单个删除
     */
    public ResponseDTO<String> delete(Integer workingHoursId) {
        if (null == workingHoursId){
            return ResponseDTO.ok();
        }
        WorkingHoursEntity entity = workingHoursDao.selectById(workingHoursId);
        entity.setDeletedFlag(true);
        workingHoursDao.updateById(entity);
        return ResponseDTO.ok();
    }

    /**
     * 通过工号和日期验证
     */
    public ResponseDTO<String> queryByNumberAndDate(String jobNumber,@PathVariable String overtimeData) {
        QueryWrapper<WorkingHoursEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("job_number",jobNumber);
        queryWrapper.eq("overtime_data",overtimeData);
        queryWrapper.eq("deleted_flag",false);
        WorkingHoursEntity workingHoursEntity = workingHoursDao.selectOne(queryWrapper);
        if(workingHoursEntity != null){
            return ResponseDTO.error(UserErrorCode.ALREADY_EXIST);
        }else{
            return ResponseDTO.ok();
        }
    }

    /**
     * 获取导出数据
     */
    public List<WorkingHoursExcelVO> getExcelExportData(WorkingHoursQueryForm queryForm) {
        queryForm.setDeletedFlag(false);
        //部门查询
        List<Long> departmentIds = queryForm.getDepartmentIds();
        List<String> jobNumbers = queryForm.getCheckedMemberNumbers();
        return workingHoursDao.selectExcelExportData(queryForm,departmentIds,jobNumbers);
    }

    /**
     * 获取加班月结导出数据
     */
    public List<WorkingHoursMonthExcelVO> getExcelMonthExportData(WorkingHoursQueryForm queryForm) {
        queryForm.setDeletedFlag(false);
        return workingHoursDao.getExcelMonthExportData(queryForm);
    }

    /**
     * 周日PDF预览及导出
     */
    public List<WorkingHoursPdfVO> selectPdfDownLoadData(WorkingHoursQueryForm queryForm) {
        queryForm.setDeletedFlag(false);
        if(queryForm.getOvertimeData() == null){
            queryForm.setOvertimeData(LocalDate.now());
        }
        //查询部门
        List<Long> departmentIds = queryForm.getDepartmentIds();
        List<String> memberNumbers = queryForm.getCheckedMemberNumbers();
        List<WorkingHoursPdfVO> workingHoursPdfVOS = workingHoursDao.selectPdfDownLoadData(queryForm, departmentIds,memberNumbers);
        for(WorkingHoursPdfVO overTimeVO :workingHoursPdfVOS ){
            if(overTimeVO.getPositionId() !=null){
                overTimeVO.setPositionName(positionDao.selectById(overTimeVO.getPositionId()).getPositionName());
            }else{
                overTimeVO.setPositionName("");
            }
            queryForm.setJobNumber(overTimeVO.getJobNumber());
            LocalDate today = LocalDate.now(); // 获取当前日期
            LocalDate firstDayOfMonth = today.with(TemporalAdjusters.firstDayOfMonth()); // 获取当月第一天
            queryForm.setStartTime(firstDayOfMonth);
            overTimeVO.setTotalNum(workingHoursDao.selectPdfMonthOverTime(queryForm));
        }
        return workingHoursPdfVOS;
    }

    /**
     * 周一到周五PDF预览及导出
     */
    public List<WorkingHoursPdfOverTimeVO> selectPdfOverTimeData(WorkingHoursQueryForm queryForm) {
        queryForm.setDeletedFlag(false);
        if(queryForm.getOvertimeData() == null){
            queryForm.setOvertimeData(LocalDate.now());
        }
        //查询部门
        List<Long> departmentIds = queryForm.getDepartmentIds();
        List<String> memberNumbers = queryForm.getCheckedMemberNumbers();
        List<WorkingHoursPdfOverTimeVO> workingHoursPdfOverTimeVOS = workingHoursDao.selectPdfOverTimeData(queryForm,departmentIds,memberNumbers);
        for(WorkingHoursPdfOverTimeVO overTimeVO :workingHoursPdfOverTimeVOS ){
            if(overTimeVO.getPositionId() !=null){
                overTimeVO.setPositionName(positionDao.selectById(overTimeVO.getPositionId()).getPositionName());
            }else{
                overTimeVO.setPositionName("");
            }
            queryForm.setJobNumber(overTimeVO.getJobNumber());
            overTimeVO.setTotalNum(workingHoursDao.selectPdfMonthOverTime(queryForm));
        }
        return workingHoursPdfOverTimeVOS;
    }

    /**
     * 批量审批
     *
     * @param idList
     * @return
     */
    public ResponseDTO<String> batchApprove(List<Integer> idList) {
        if (CollectionUtils.isEmpty(idList)){
            return ResponseDTO.ok();
        }
        for(Integer id : idList){
            WorkingHoursEntity workingHoursEntity = new WorkingHoursEntity();
            workingHoursEntity.setWorkingHoursId((long)id);
            workingHoursEntity.setAllowFlag(1);
            workingHoursEntity.setAllowTime(SmartLocalDateUtil.toLocalDateTime(new Date()));
            workingHoursDao.updateById(workingHoursEntity);
        }
        return ResponseDTO.ok();
    }

    //-----------------------------------------------第三方嘉宝系统数据对接-----------------------------------------------------------------

    /**
     * 嘉宝数据查询
     */
    public void analysis(WorkingOvertimeAnalysisForm queryForm){
        //分析同步
        QueryWrapper<WorkingHoursEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.ge("overtime_data",queryForm.getStartTime());
        queryWrapper.le("overtime_data",queryForm.getEndTime());
        List<Integer> flags = new ArrayList<>();
        flags.add(0);
        flags.add(3);
        queryWrapper.in("allow_flag",flags);
        List<WorkingHoursEntity> workingHoursEntities = workingHoursDao.selectList(queryWrapper);
        for(WorkingHoursEntity entity : workingHoursEntities){
            try {
                //第一步：加载数据库驱动程序，此时不需要实例化，因为会由容器自己负责
                Class.forName(DBDRIVER);
                //第二步：根据连接协议、用户名、密码连接数据库
                Connection conn = DriverManager.getConnection(DBURL, USER, PASSWORD);
                log.info("连接成功!");
                String sql = "SELECT * FROM attendancebook b left join  employee e  on b.emp_id = e.emp_id where the_date = ? and e.job_number = ?";
                PreparedStatement preparedStatement = conn.prepareStatement(sql);
                String theDate = entity.getOvertimeData().toString().replace("-", ".");
                preparedStatement.setString(1, theDate);
                preparedStatement.setString(2, entity.getJobNumber());
                ResultSet rs = preparedStatement.executeQuery();//使用ResultSet接收数据

                while (rs.next()) {
                    String checkJb = rs.getString("check_on").trim();//加班开始时间
                    String check0ff = rs.getString("check_off").trim();//加班结束时间
                    log.info("加班开始时间:{}",checkJb);
                    log.info("加班结束时间:{}",check0ff);
                    if(StrUtil.isNotBlank(checkJb) && StrUtil.isNotBlank(check0ff)) {
                        String shift = rs.getString("shift").trim();//班别
                        log.info("班别:{}",shift);
                        String overtime = "";
                        String checkOn = "";
                        if (BanBieTypeEnum.ZAOBAN.getValue().equals(shift)) {
                            checkOn = "18:00";
                            LocalTime startTime = LocalTime.parse(checkOn);
                            LocalTime endTime = LocalTime.parse(check0ff);
                            long minutes = ChronoUnit.MINUTES.between(startTime, endTime);
                            long round = minutes / (long) 60;  //取整
                            long comp = minutes % (long) 60;   //求余
                            //早班、大夜班超过2小时按2小时计算，不超过以半小时为系数计算
                            //白班八点到八点算十小时，不超过以半小时为系数计算
                            if(round >= 2) {
                                overtime = "2";
                            }else if(round >= 1 && round < 2) {
                                if(comp < 60 && comp >= 30) {
                                    overtime = "1.5";
                                }else{
                                    overtime = "1";
                                }
                            }else if(round < 1) {
                                if(comp < 60 && comp >= 30) {
                                    overtime = "0.5";
                                }
                            }
                        }else if (BanBieTypeEnum.BAIBAN.getValue().equals(shift)){
                            overtime = DateUtils.TimeDifference(checkJb,check0ff);
                        }else if (BanBieTypeEnum.DAYEBAN.getValue().equals(shift) || BanBieTypeEnum.DAYEBAN1.getValue().equals(shift)) {
                            checkOn = "06:00";
                            LocalTime startTime = LocalTime.parse(checkOn);
                            LocalTime endTime = LocalTime.parse(check0ff);
                            long minutes = ChronoUnit.MINUTES.between(startTime, endTime);
                            long round = minutes / (long) 60;  //取整
                            long comp = minutes % (long) 60;   //求余
                            //计算工时,超过2小时按2小时计算，不超过以半小时为系数计算
                            if(round >= 2) {
                                overtime = "2";
                            }else if(round >= 1 && round < 2) {
                                if(comp < 60 && comp >= 30) {
                                    overtime = "1.5";
                                }else{
                                    overtime = "1";
                                }
                            }else if(round < 1) {
                                if(comp < 60 && comp >= 30) {
                                    overtime = "0.5";
                                }
                            }
                        }
                        String empid = rs.getString("emp_id");//部门ID
                        String updatesql = "update attendancebook set  overtime1 = '" + overtime + "' where emp_id = '" + empid + "' and the_date = '" + theDate + "'";
                        Statement statement = conn.createStatement();
                        int i = statement.executeUpdate(updatesql);
                        log.info("更新成功，影响行数:{}", i);//输出
                    }
                }
                conn.close();
            } catch (ClassNotFoundException e) {
                log.info("JDBC驱动未找到！");
                e.printStackTrace();
            } catch (SQLException e) {
                log.info("数据库连接失败！");
                e.printStackTrace();
            }
        }
    }


    /**
     * 同步嘉宝人员数据
     */
    public void batchSyncEmployee(){
        try {
            //第一步：加载数据库驱动程序，此时不需要实例化，因为会由容器自己负责
            Class.forName(DBDRIVER);
            //第二步：根据连接协议、用户名、密码连接数据库
            Connection conn = DriverManager.getConnection(DBURL,USER,PASSWORD);
            log.info("连接成功!");
            String sql = "SELECT * FROM employee e  where e.status='在职中'";
            Statement statement = conn.createStatement();
            ResultSet rs = statement.executeQuery(sql);//使用ResultSet接收数据
            while(rs.next()) {
                String jobNumber = rs.getString("job_number");//工号
                String empName = rs.getString("emp_name");//名称
                String phone = rs.getString("c37");//手机号
                String status = rs.getString("status");//状态
                String gender = rs.getString("c15");//性别
                EmployeeEntity employeeEntity = employeeDao.getByLoginName(jobNumber, null);
                if(employeeEntity == null){
                    EmployeeEntity entity = new EmployeeEntity();
                    entity.setActualName(empName.trim());
                    entity.setPhone(StrUtil.isNotEmpty(phone)?phone.trim():null);
                    entity.setLoginName(jobNumber.trim());
                    entity.setLoginPwd("40cc20b8891cd3fd1f008ea7f4ac17c3");  //123456密码加密
                    entity.setGender(StrUtil.isNotEmpty(gender)?("男".equals(gender.trim())?1:2):0);
                    entity.setDisabledFlag(false);
                    entity.setDepartmentId((long)5);
                    entity.setDeletedFlag(false);
                    entity.setAdministratorFlag(false);
                    employeeDao.insert(entity);
                }else{
                    employeeEntity.setActualName(empName.trim());
                    employeeEntity.setPhone(phone.trim());
                    employeeEntity.setLoginName(jobNumber.trim());
                    employeeDao.updateById(employeeEntity);
                }
            }
            conn.close();
        } catch (ClassNotFoundException e) {
            log.info("JDBC驱动未找到！");
            e.printStackTrace();
        } catch (SQLException e) {
            log.info("数据库连接失败！");
            e.printStackTrace();
        }
    }


}
